package top.lingkang.hibernate5.dao;

import org.hibernate.transform.ResultTransformer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author lingkang
 * created by 2023/10/7
 * 结果进行转换，可以自定义返回bean时使用<hr/>
 * <pre>
 * List<UserConsumeVo> resultList = sessionFactory.getCurrentSession().createQuery(<br>
 * "select o.price as price,o.completionTime as completionTime,o.status as status,o.id as orderId,o.description as description" +<br>
 *         " from UserEntity u left join OrderUserEntity ou on u.id=ou.userId" +<br>
 *         " left join OrderEntity o on o.id=ou.orderId where u.openId=?1" +<br>
 *         " and o.status in ('1','2') order by o.id desc"<br>
 * ).setResultTransformer(new TupleResult(UserConsumeVo.class))// 此处设置自定义解析<br>
 * .setParameter(1, openId)<br>
 * .list();<br>
 * </pre>
 */
public class TupleResult implements ResultTransformer {
    private static final Logger log = LoggerFactory.getLogger(TupleResult.class);
    private Class<?> resultClass;

    public TupleResult(Class<?> resultClass) {
        this.resultClass = resultClass;
    }

    @Override
    public Object transformTuple(Object[] tuple, String[] aliases) {
        if (tuple.length == 1)
            return tuple[0];
        if (resultClass.isAssignableFrom(Map.class)) {
            Map<String, Object> map = new HashMap<>();
            for (int i = 0; i < aliases.length; i++) {
                String name = aliases[i];
                if (name != null)
                    map.put(name, tuple[i]);
                else
                    map.put(i + "", tuple[i]);
            }
            return map;
        }
        try {
            boolean isEmpty = true;
            Object instance = resultClass.newInstance();
            for (Field field : resultClass.getDeclaredFields()) {
                for (int i = 0; i < aliases.length; i++) {
                    if (field.getName().equals(aliases[i])) {
                        field.setAccessible(true);
                        field.set(instance, tuple[i]);
                        if (isEmpty) isEmpty = false;
                        break;
                    }
                }
            }
            if (isEmpty) {
                log.warn("返回的结果属性与查询的列不匹配，将返回null值，sql语句需要使用as映射到结果属性上。例如：select id as id from user");
                return null;
            }
            return instance;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public List transformList(List collection) {
        return collection;
    }
}
